import React, { useCallback } from 'react';
import { Editor } from '@tiptap/react';
import { Document, Packer, Paragraph, TextRun, Table as DocxTable, TableRow as DocxTableRow, TableCell as DocxTableCell, ImageRun, WidthType } from 'docx';
import { saveAs } from 'file-saver';
import * as XLSX from 'xlsx';
import html2pdf from 'html2pdf.js';
import dayjs from 'dayjs';
import pdfMake from "pdfmake/build/pdfmake";
import * as pdfFonts from 'pdfmake/build/vfs_fonts';

// 初始化字体
// (window as any).pdfMake = pdfMake;
// pdfMake.vfs = pdfFonts.default.pdfMake.vfs;

// 类型定义
interface ExportButtonProps {
  editor: Editor;
  type: 'word' | 'excel' | 'pdf';
  icon: string;
  title?: string;
}

interface ExportOptions {
  filename: string;
  content: any;
}

interface JSONContent {
  type: string;
  content?: JSONContent[];
  attrs?: {
    src?: string;
    [key: string]: any;
  };
  text?: string;
}

const ExportButton: React.FC<ExportButtonProps> = ({
  editor,
  type,
  icon,
  title
}) => {
  // 生成文件名
  const generateFilename = useCallback((ext: string) => {
    return `document-${dayjs().format('YYYY-MM-DD-HH-mm-ss')}.${ext}`;
  }, []);

  // 处理段落内容
  const handleParagraph = (node: JSONContent) => {
    return new Paragraph({
      children: [new TextRun(node.content?.[0]?.text || '')],
      style: { spacing: { after: 200 } }
    });
  };

  // 添加后端 API 地址配置
const API_BASE_URL = 'http://localhost:4334';
// 修改图片处理函数
const handleImage = async (node: any) => {
  try {
    const url = node.attrs.src;
    // 如果是 base64 图片直接处理
    if (url.startsWith('data:image')) {
      const base64Data = url.split(',')[1];
      const binaryData = atob(base64Data);
      const buffer = new ArrayBuffer(binaryData.length);
      const intArray = new Uint8Array(buffer);
      for (let i = 0; i < binaryData.length; i++) {
        intArray[i] = binaryData.charCodeAt(i);
      }
      return new Paragraph({
        children: [
          new ImageRun({
            data: buffer,
            transformation: {
              width: 400,
              height: 300,
            },
            type: url.split(';')[0].split('/')[1] || 'png'
          })
        ],
        spacing: { after: 200 }
      });
    }
    // 对于远程图片，通过后端处理
    const response = await fetch(`${API_BASE_URL}/api/process-image`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({ imageUrl: url })
    });
    if (!response.ok) {
      throw new Error('图片处理请求失败');
    }
    const result = await response.json();
    if (!result.success) {
      throw new Error('图片处理失败');
    }
    // 直接使用返回的 base64 数据
    const binaryData = atob(result.data);
    const buffer = new ArrayBuffer(binaryData.length);
    const intArray = new Uint8Array(buffer);
    for (let i = 0; i < binaryData.length; i++) {
      intArray[i] = binaryData.charCodeAt(i);
    }
    return new Paragraph({
      children: [
        new ImageRun({
          data: buffer,
          transformation: {
            width: 400,
            height: 300,
          },
          type: 'png'
        })
      ],
      spacing: { after: 200 }
    })    
  } catch (error) {
    console.error('图片处理失败:', error);
    return new Paragraph({
      children: [new TextRun(`[图片导出失败: ${error.message}]`)],
      style: { color: 'red' }
    });
  }
};

  // 导出到 Word
  const exportToWord = async () => {
    const content = editor.getJSON() as { content: JSONContent[] };
    const sections: any[] = [];
    for (const node of content.content || []) {
      switch (node.type) {
        case 'paragraph':
          sections.push(handleParagraph(node));
          break;
        case 'image':
          sections.push(await handleImage(node));
          break;
        case 'table':
          if (node.content && node.content.length > 0) {
            const tableRows = node.content.map((row: JSONContent) =>
              new DocxTableRow({
                children: (row.content || []).map((cell: JSONContent) =>
                  new DocxTableCell({
                    children: [handleParagraph(cell.content?.[0] || { type: 'paragraph', content: [] })],
                    margins: { top: 100, bottom: 100, left: 100, right: 100 }
                  })
                ),
              })
            );
            sections.push(
              new DocxTable({
                rows: tableRows,
                width: { size: 8500, type: WidthType.DXA },
                margins: { top: 100, bottom: 100, left: 100, right: 100 },
                columnWidths: Array(tableRows[0]?.cells?.length || 1)
                  .fill(8500 / (tableRows[0]?.cells?.length || 1))
              })
            );
          }
          break;
      }
    }
    const doc = new Document({
      sections: [{ properties: {}, children: sections }],
      styles: {
        paragraphStyles: [{
          id: 'normal',
          name: 'Normal',
          run: { size: 24, font: '宋体' },
          paragraph: { spacing: { after: 200 } }
        }]
      }
    });
    try {
      const blob = await Packer.toBlob(doc);
      saveAs(blob, generateFilename('docx'));
    } catch (error) {
      throw new Error('Word文档生成失败');
    }
  };

  // 导出到 Excel
  const exportToExcel = () => {
    const content = editor.getJSON();
    const data = (content.content || [])
      .filter(node => node.type === 'paragraph')
      .map(node => [node.content?.[0]?.text || ''])
      .filter(row => row[0] !== '');

    try {
      const ws = XLSX.utils.aoa_to_sheet(data);
      const wb = XLSX.utils.book_new();
      XLSX.utils.book_append_sheet(wb, ws, "Sheet1");
      XLSX.writeFile(wb, generateFilename('xlsx'));
    } catch (error) {
      throw new Error('Excel文件生成失败');
    }
  };

  // 导出到 PDF
  const exportToPDF = () => {
    const element = document.querySelector('.ProseMirror');
    if (!element) throw new Error('找不到编辑器内容');
    const style = document.createElement('style');
    style.textContent = `
      .ProseMirror table {
        border-collapse: collapse;
        width: 100%;
        margin: 10px 0;
      }
      .ProseMirror td, .ProseMirror th {
        border: 1px solid #000;
        padding: 8px;
        text-align: left;
      }
      .ProseMirror th {
        background-color: #f2f2f2;
      }
    `;
    document.head.appendChild(style);
    const opt = {
      margin: 1,
      filename: generateFilename('pdf'),
      image: { type: 'jpeg', quality: 0.98 },
      html2canvas: {
        scale: 2,
        useCORS: true,
        logging: true,
        allowTaint: true,
        scrollX: 0,
        scrollY: 0,
        windowWidth: document.documentElement.offsetWidth,
        windowHeight: document.documentElement.offsetHeight
      },
      jsPDF: { unit: 'in', format: 'a4', orientation: 'portrait' }
    };
    return new Promise<void>((resolve, reject) => {
      const cleanup = () => document.head.removeChild(style);
      Promise.all(
        Array.from(element.querySelectorAll('img'))
          .map(img => img.complete ? Promise.resolve() : new Promise(res => {
            img.onload = res;
            img.onerror = res;
          }))
      )
        .then(() => {
          html2pdf()
            .set(opt)
            .from(element)
            .save()
            .then(() => {
              cleanup();
              resolve();
            })
            .catch(() => {
              cleanup();
              reject(new Error('PDF导出失败'));
            });
        })
        .catch(() => {
          cleanup();
          reject(new Error('图片加载失败'));
        });
    });
  };

  // 统一的导出处理函数
  const handleExport = async () => {
    if (!editor) return;

    try {
      switch (type) {
        case 'word':
          await exportToWord();
          break;
        case 'excel':
          exportToExcel();
          break;
        case 'pdf':
          await exportToPDF();
          break;
      }
    } catch (error) {
      console.error(`导出${type.toUpperCase()}失败:`, error);
      alert(`导出失败，请稍后重试`);
    }
  };

  return (
    <button
      onClick={handleExport}
      className="toolbar-button"
      title={title}
    >
      <i className="icon">{icon}</i>
    </button>
  );
};

export default ExportButton;